home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Panorama / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].zip / Panorama - Disk 19D (1987-07-22)(Pacific North-West Amigas Club)[WB].adf / PopCLI3 / PopCLI.c < prev    next >
C/C++ Source or Header  |  1987-06-25  |  15KB  |  467 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /* |_o_o|\\ Copyright (c) 1986 The Software Distillery.  All Rights Reserved */
  3. /* |. o.| || This program may not be distributed without the permission of   */
  4. /* | .  | || the authors.                                                    */
  5. /* | o  | ||    Dave Baker     Ed Burnette  Stan Chow    Jay Denebeim        */
  6. /* |  . |//     Gordon Keener  Jack Rouse   John Toebes  Doug Walker         */
  7. /* ======          BBS:(919)-471-6436      VOICE:(919)-469-4210              */ 
  8. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9. /*
  10.  * VERY loosely based on the input.device example by Rob Peck, 12/1/85
  11.  */
  12.  
  13. /* * * * * * * * * INCLUDE FILES * * * * * * * * * * * */
  14. #include <exec/types.h>
  15. #include <exec/nodes.h>
  16. #include <exec/lists.h>
  17. #include <exec/memory.h>
  18. #include <exec/interrupts.h>
  19. #include <exec/ports.h>
  20. #include <exec/libraries.h>
  21. #include <exec/io.h>
  22. #include <exec/tasks.h>
  23. #include <exec/execbase.h>
  24. #include <exec/devices.h>
  25. #include <devices/timer.h>
  26. #include <devices/input.h>
  27. #include <devices/inputevent.h>
  28. #include <intuition/intuition.h>
  29. #include <libraries/dos.h>
  30. #include <graphics/gfxmacros.h>
  31. #include <hardware/custom.h>
  32. #include <hardware/dmabits.h>
  33. #include <proto/dos.h>
  34. #include <proto/exec.h>
  35. #include <proto/intuition.h>
  36. #include <proto/graphics.h>
  37. #include <string.h>
  38.  
  39. /* * * * * * * * * * * CONSTANTS * * * * * * * * * * * * */
  40. #define PORTNAME     "POPCLI_III.port"
  41. #define TIMEINTERVAL 1L      /* in seconds */
  42. #define DEFTIME      300     /* two minute timeout */
  43. #define MAXCMD       200
  44. #define DEFKEY    0x45
  45. #define DEFCMD    "NEWCLI >NIL: <NIL:"
  46. #define KILLMSG "\x9B1mPOPCLI III\x9B0m Terminating\n"
  47. #define BANNER "\x9B0;33mPOPCLI III\x9B0m by John Toebes - Copyright \xa9 1987 The Software Distillery\n 235 Trillingham Ln, Cary NC 27511   BBS:(919)-471-6436\n"
  48. #define BANNER1 "Usage: \x9B1mPOPCLI\x9B0m [secs [command]]\nsecs is number of seconds before blanking screen\ncommand is to be executed when Left Amiga-Escape is pressed\n"
  49. /* * * * * * * * * * * GLOBAL VARIABLES * * * * * * * * * */
  50. typedef struct
  51.    {
  52.    struct Task          *buddy;
  53.    ULONG                 creatclisig;
  54.    ULONG                 unblanksig;
  55.    ULONG                 noevents;
  56.    short                 creatsignum;
  57.    short                 blanksignum;
  58.    short                 key;
  59.    struct Screen        *blankscreen;
  60.    } GLOBAL_DATA;
  61.  
  62. struct MsgPort *FindPort(), *CreatePort();
  63. void DeletePort();
  64.  
  65. struct OURMSG {
  66.  struct Message msgpart;
  67.  short key;
  68.  short interval;
  69.  char cmd[MAXCMD];
  70.  };
  71.  
  72. /* Declarations for CBACK */
  73. extern BPTR _Backstdout;         /* standard output when run in background */
  74. long _BackGroundIO = 1;          /* Flag to tell it we want to do I/O      */
  75. long _stack = 4000;              /* Amount of stack space our task needs   */
  76. char *_procname = "PopCLI III";  /* The name of the task to create         */
  77. long _priority = 20;             /* The priority to run us at              */
  78.  
  79. /************************************************************************/
  80. /* the handler subroutine - called through the handler stub             */
  81. /************************************************************************/
  82. struct InputEvent *myhandler(ev, gptr)
  83. struct InputEvent *ev;      /* and a pointer to a list of events */
  84. register GLOBAL_DATA *gptr;      /* Everything we need to know about */
  85.    {
  86.    register struct InputEvent *ep, *laste;
  87.  
  88.    /* run down the list of events to see if they pressed the magic button */
  89.    for (ep = ev, laste = NULL; ep != NULL; ep = ep->ie_NextEvent)
  90.       {
  91.       if ((ep->ie_Class == IECLASS_RAWKEY)    &&
  92.           (ep->ie_Code  == gptr->key)         &&
  93.           (ep->ie_Qualifier & IEQUALIFIER_LCOMMAND))
  94.          {
  95.          /* we can handle this event so take it off the chain */
  96.          if (laste == NULL)
  97.             ev = ep->ie_NextEvent;
  98.          else
  99.             laste->ie_NextEvent = ep->ie_NextEvent;
  100.          /* now tell him to create the new cli */
  101.          Signal(gptr->buddy, gptr->creatclisig);
  102.          }
  103.       else
  104.          laste = ep;
  105.  
  106.       if (ep->ie_Class != IECLASS_TIMER)
  107.          {
  108.          gptr->noevents = 0;
  109.          if (gptr->blankscreen != NULL)
  110.             Signal(gptr->buddy, gptr->unblanksig);
  111.          }
  112.       }
  113.  
  114.    /* pass on the pointer to the event */
  115.    return(ev);
  116.    }
  117.  
  118. /* * * * * * * * * * * EXTERNAL ROUTINES * * * * * * * * * */
  119. struct IntuitionBase *IntuitionBase;
  120. struct GfxBase       *GfxBase;
  121. struct DosLibrary    *DosBase;
  122. extern struct Custom custom;
  123. struct NewScreen      NewScreen = 
  124.    { 0, 0, 320, 30, 1, 0, 1, NULL, CUSTOMSCREEN, NULL, NULL, NULL, NULL };
  125.  
  126. extern struct MsgPort  *CreatePort();
  127. struct IOStdReq *CreateIOReq(struct MsgPort *, int);
  128. void DeleteIOReq(struct IOStdReq *);
  129. extern void             HandlerInterface();
  130.  
  131. /************************************************************************/
  132. /* Queue a timer to go off in a given number of seconds                 */
  133. /************************************************************************/
  134. void QueueTimer(tr,seconds)
  135. struct timerequest *tr;
  136. ULONG seconds;
  137.    {
  138.    tr->tr_node.io_Command = TR_ADDREQUEST;   /* add a new timer request */
  139.    tr->tr_time.tv_secs =  seconds;            /* seconds */
  140.    tr->tr_time.tv_micro = 0;
  141.    SendIO( (struct IORequest *)tr );
  142.    }
  143.  
  144. /************************************************************************/
  145. /* the main program to do the popcli stuff                              */
  146. /************************************************************************/
  147. void _main(cmd)
  148. char *cmd;
  149.    {
  150.    struct MsgPort *port;
  151.    int stay = 0;
  152.    struct OURMSG *msg;
  153.  
  154.    char cmdstr[MAXCMD];
  155.    short key, timeout;
  156.    BPTR  nullfh;
  157.    ULONG sig, timersig;
  158.    struct timerequest *timerreq;
  159.    struct MsgPort     *timerport;
  160.    struct MsgPort     *inputDevPort;
  161.    struct IOStdReq    *inputRequestBlock;
  162.    struct Interrupt      handlerStuff;
  163.    GLOBAL_DATA global;
  164.  
  165.    global.creatsignum  = -1;
  166.    global.blanksignum  = -1;
  167.    timerreq            = NULL;
  168.    timerport           = NULL;
  169.    inputDevPort        = NULL;
  170.    inputRequestBlock   = NULL;
  171.  
  172.    /* now see if we are already installed */
  173.    if ((port = FindPort(PORTNAME)) == NULL)
  174.       {
  175.       stay = 1; /* remember to hang around when we are done */
  176.       /* not installed, we need to install our own port */
  177.       if ((port = CreatePort(PORTNAME,0)) == NULL)
  178.          goto abort;
  179.       }
  180.  
  181.    /* now send the parameter to the waiting program */
  182.    if ((msg = (struct OURMSG *)
  183.               AllocMem(sizeof(struct OURMSG), MEMF_CLEAR|MEMF_PUBLIC)) == NULL)
  184.       goto abort;
  185.  
  186.    /* fill in the message information */
  187.    msg->msgpart.mn_Length = sizeof(struct OURMSG);
  188.  
  189.    strcpy(cmdstr, DEFCMD);
  190.  
  191.    /* if we were run from CLI then output our banner and process parameters */
  192.    if (cmd && *cmd)
  193.       {
  194.       /* display our copyright */
  195.       if (stay && _Backstdout)
  196.          Write(_Backstdout, BANNER, sizeof(BANNER));
  197.  
  198.       /* skip over any leading spaces in the command line */
  199.       while(*cmd != ' ')
  200.          cmd++;
  201.       while(*cmd == ' ')
  202.          cmd++;
  203.  
  204.       /* see if they are trying to kill us. */
  205.       if (!stricmp(cmd, "QUIT\n"))
  206.          {
  207.          timeout = -1;
  208.          if (_Backstdout)
  209.             Write(_Backstdout, KILLMSG, sizeof(KILLMSG));
  210.          }
  211.       else if ((*cmd < ' ') && _Backstdout)
  212.          {
  213.          Write(_Backstdout, BANNER1, sizeof(BANNER1));
  214.          key = DEFKEY;
  215.          timeout = DEFTIME;
  216.          msg->cmd[0] = 0;  /* don't change the command string */
  217.          }
  218.       else
  219.          {
  220.          /* see if they gave us a number to control the interval of checking */
  221.          timeout = 0;
  222.          key = 0;
  223.  
  224.          while ((*cmd >= '0') && (*cmd <= '9'))
  225.             /* Multiply it by 10 without using a subroutine */
  226.             timeout = (timeout*10) + *cmd++ - '0';
  227.  
  228.          if (timeout <= 0)
  229.             timeout = DEFTIME;
  230.  
  231.          while (*cmd == ' ') cmd++;
  232.  
  233.          /* see if they gave us a number to control the interval of checking */
  234.          while ((*cmd >= '0') && (*cmd <= '9'))
  235.             /* Multiply it by 10 without using a subroutine */
  236.             key = (key*10) + *cmd++ - '0';
  237.  
  238.          if (key == 0)
  239.             key = DEFKEY;
  240.  
  241.          while (*cmd == ' ') cmd++;
  242.          strcpy(msg->cmd, cmd);
  243.          msg->cmd[strlen(cmd)-1] = 0;  /* wipe out the EOL character */
  244.          }
  245.       }
  246.    else
  247.       {
  248.       timeout = DEFTIME;
  249.       key = DEFKEY;
  250.       msg->cmd[0] = 0;
  251.       }
  252.  
  253.    msg->interval = timeout;
  254.    msg->key = key;
  255.  
  256.    PutMsg(port,(struct Message *)msg);
  257.  
  258.    if (!stay) goto abort;
  259.  
  260.    /* Lst the original window go away */
  261.    if (_Backstdout)
  262.       Close(_Backstdout);
  263.  
  264.    _Backstdout = 0;
  265.  
  266.    global.blankscreen = NULL;
  267.  
  268.    global.buddy = FindTask(0);
  269.    global.noevents = 0;
  270.  
  271.    /* set the input and output streams to 0 so execute doen't complain */
  272.    nullfh = Open("NIL:", MODE_NEWFILE);
  273.  
  274.    if (((inputDevPort = CreatePort(0,0)) == NULL)                          ||
  275.  
  276.       ((inputRequestBlock =
  277.           CreateIOReq(inputDevPort, sizeof(struct IOStdReq))) == NULL)     ||
  278.  
  279.       ((timerport = CreatePort(0,0)) == NULL)                              ||
  280.  
  281.       ((timerreq  = (struct timerequest *)
  282.           CreateIOReq(timerport, sizeof(struct timerequest))) == NULL)     ||
  283.  
  284.       ((global.creatsignum = AllocSignal(-1)) == -1)                       ||
  285.  
  286.       ((global.blanksignum = AllocSignal(-1)) == -1)                       ||
  287.  
  288.       ((GfxBase = (struct GfxBase *)
  289.                   OpenLibrary("graphics.library", 0)) == NULL)             ||
  290.  
  291.       ((IntuitionBase = (struct IntuitionBase *)
  292.                         OpenLibrary("intuition.library", 0)) == NULL)      ||
  293.       OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timerreq, 0)  ||
  294.  
  295.       OpenDevice("input.device",0,(struct IORequest *)inputRequestBlock,0))
  296.  
  297.       goto abort;
  298.  
  299.    handlerStuff.is_Data = (APTR)&global;
  300.    handlerStuff.is_Code = HandlerInterface;
  301.    handlerStuff.is_Node.ln_Pri = 51;
  302.  
  303.    timersig            = (1 << timerport->mp_SigBit);
  304.    global.creatclisig  = 1 << global.creatsignum;
  305.    global.unblanksig   = 1 << global.blanksignum;
  306.  
  307.    inputRequestBlock->io_Command = IND_ADDHANDLER;
  308.    inputRequestBlock->io_Data    = (APTR)&handlerStuff;
  309.  
  310.    DoIO((struct IORequest *)inputRequestBlock);
  311.  
  312.    QueueTimer(timerreq, TIMEINTERVAL);
  313.  
  314.    for(;;)         /* FOREVER */
  315.       {
  316.       sig = Wait( global.creatclisig | global.unblanksig | timersig );
  317.  
  318.       /* see if they asked us to change the interval */
  319.       if ((msg = (struct OURMSG *)GetMsg(port)) != NULL)
  320.          {
  321.          if (msg->cmd[0]) strcpy(cmdstr, msg->cmd);
  322.          global.key = msg->key;
  323.          timeout    = msg->interval;
  324.          FreeMem((char *)msg, msg->msgpart.mn_Length);
  325.  
  326.          if (global.key == 0) goto abort;
  327.          }
  328.  
  329.       if ((sig & global.unblanksig) && global.blankscreen)
  330.          {
  331.          CloseScreen(global.blankscreen);
  332.      ON_DISPLAY
  333.          global.blankscreen = NULL;
  334.          }
  335.  
  336.       if (sig & global.creatclisig)
  337.          {
  338.          WBenchToFront();
  339.          (void)Execute(cmdstr,nullfh,nullfh);
  340.          }
  341.  
  342.       if (sig & timersig)
  343.          {
  344.          /* get rid of the message */
  345.          (void)GetMsg(timerport);
  346.          QueueTimer(timerreq, TIMEINTERVAL);
  347.  
  348.          if ((global.noevents++ >= timeout) && (global.blankscreen == NULL))
  349.             {
  350.             if ( (global.blankscreen = OpenScreen(&NewScreen)) != NULL)
  351.                {
  352.                SetRGB4(&(global.blankscreen->ViewPort), 0, 0, 0, 0);
  353.                OFF_DISPLAY
  354.                }
  355.             }
  356.          }
  357.  
  358.       /* Force our screen to front on a regular basis to handle something   */
  359.       /* that might put their stuff in front of us while we are supposed to */
  360.       /* Be blanking the screen.                                            */
  361.       if (global.blankscreen)
  362.          {
  363. #if 0
  364.          /* Unfortunately doing this causes the screen to flash momentarily */
  365.          /* Which makes it look ugly.  Perhaps someone can come up with a   */
  366.          /* Better way to force us upfront..                                */
  367.          ScreenToFront(global.blankscreen);
  368. #endif
  369.          OFF_DISPLAY
  370.          }
  371.       }
  372.  
  373. abort:
  374.    if (timerreq != NULL)
  375.       {
  376.       if (timerreq->tr_node.io_Device != NULL)
  377.          CloseDevice((struct IORequest *)timerreq);
  378.       DeleteIOReq((struct IOStdReq *)timerreq);
  379.       }
  380.    if (inputRequestBlock != NULL)
  381.       {
  382.       if (inputRequestBlock->io_Device != NULL)
  383.          {
  384.          inputRequestBlock->io_Command = IND_REMHANDLER;
  385.          inputRequestBlock->io_Data = (APTR)&handlerStuff;
  386.          DoIO((struct IORequest *)inputRequestBlock);
  387.  
  388.          CloseDevice((struct IORequest *)inputRequestBlock);
  389.          }
  390.       DeleteIOReq(inputRequestBlock);
  391.       }
  392.    if (timerport != NULL)          DeletePort(timerport);
  393.    if (global.creatsignum != -1)   FreeSignal(global.creatsignum);
  394.    if (global.blanksignum != -1)   FreeSignal(global.blanksignum);
  395.    if (global.blankscreen != NULL) CloseScreen(global.blankscreen);
  396.    if (IntuitionBase != NULL)      CloseLibrary((struct Library *)IntuitionBase);
  397.    if (GfxBase != NULL)            CloseLibrary((struct Library *)GfxBase);
  398.    if (inputDevPort != NULL)       DeletePort(inputDevPort);
  399.    if (_Backstdout)                Close(_Backstdout);
  400.    if (stay && (port != NULL))     DeletePort(port);
  401.    if (nullfh)                     Close(nullfh);
  402.    }
  403.  
  404. void MemCleanup(){}
  405.  
  406. struct MsgPort *CreatePort(name, pri)
  407. char *name;
  408. int pri;
  409. {
  410.    UBYTE sigbit;
  411.    register struct MsgPort *port;
  412.  
  413.    if ((sigbit = AllocSignal(-1)) == -1)
  414.       return((struct MsgPort *)0);
  415.  
  416.    if ((port = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),
  417.                         MEMF_CLEAR|MEMF_PUBLIC)) == 0)
  418.       {
  419.       FreeSignal(sigbit);
  420.       return((struct MsgPort *) (0));
  421.       }
  422.    port->mp_Node.ln_Name = name;
  423.    port->mp_Node.ln_Pri = pri;
  424.    port->mp_Node.ln_Type = NT_MSGPORT;
  425.    port->mp_Flags = PA_SIGNAL;
  426.    port->mp_SigBit = sigbit;
  427.    port->mp_SigTask = (struct Task *)FindTask(0);
  428.    AddPort(port);
  429.    return(port);
  430. }
  431.  
  432. void DeletePort(port)
  433. struct MsgPort *port;
  434. {
  435. RemPort(port);
  436. FreeSignal(port->mp_SigBit);
  437. FreeMem((char *)port,sizeof(struct MsgPort));
  438. }
  439.  
  440. struct IOStdReq *
  441. CreateIOReq(port, size)
  442. struct MsgPort *port;
  443. int size;
  444. {
  445.    struct IOStdReq *ioReq;
  446.  
  447.    if ((ioReq = (struct IOStdReq *)
  448.                 AllocMem(size, MEMF_CLEAR | MEMF_PUBLIC)) != NULL)
  449.       {
  450.       ioReq->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  451.       ioReq->io_Message.mn_Node.ln_Pri  = 0;
  452.       ioReq->io_Message.mn_Length       = size;
  453.       ioReq->io_Message.mn_ReplyPort    = port;
  454.       }
  455.    return(ioReq);
  456. }
  457.  
  458. void DeleteIOReq(ioReq)
  459. struct IOStdReq *ioReq;
  460. {
  461. ioReq->io_Message.mn_Node.ln_Type = 0xff;
  462. ioReq->io_Device = (struct Device *) -1;
  463. ioReq->io_Unit = (struct Unit *) -1;
  464.  
  465. FreeMem( (char *)ioReq, ioReq->io_Message.mn_Length);
  466. }
  467.